﻿#define TRACE
using System;
using System.Diagnostics;
using System.Text;
using System.Threading;

namespace TallComponents.Web.Pdf.Services
{
   /// <summary>
   /// Logger that uses .NET TraceSource named PDFWebViewer.
   /// </summary>
   internal class TraceSourceLogger : ILog
   {
      private static readonly TraceSource _source = new TraceSource( "PDFWebViewer", SourceLevels.Error | SourceLevels.Warning | SourceLevels.Information | SourceLevels.Critical );

      /// <summary>
      /// Logs an informational message.
      /// </summary>
      /// <param name="message">The message.</param>
      public void Info( string message )
      {
         Log( TraceEventType.Information, message );
      }

      /// <summary>
      /// Logs an informational message.
      /// </summary>
      /// <param name="message">The message.</param>
      /// <param name="ex">The exception or <c>null</c>.</param>
      public void Info( string message, Exception ex )
      {
         Log( TraceEventType.Information, message, ex );
      }

      /// <summary>
      /// Logs a warning message.
      /// </summary>
      /// <param name="message">The message.</param>
      public void Warn( string message )
      {
         Log( TraceEventType.Warning, message );
      }

      /// <summary>
      /// Logs a warning message.
      /// </summary>
      /// <param name="message">The message.</param>
      /// <param name="ex">The exception or <c>null</c>.</param>
      public void Warn( string message, Exception ex )
      {
         Log( TraceEventType.Warning, message, ex );
      }

      /// <summary>
      /// Logs an error message.
      /// </summary>
      /// <param name="message">The message.</param>
      public void Error( string message )
      {
         Log( TraceEventType.Error, message );
      }

      /// <summary>
      /// Logs an error message.
      /// </summary>
      /// <param name="message">The message.</param>
      /// <param name="ex">The exception or <c>null</c></param>
      public void Error( string message, Exception ex )
      {
         Log( TraceEventType.Error, message, ex );
      }

      /// <summary>
      /// Logs a fatal exception.
      /// </summary>
      /// <param name="message">The message.</param>
      public void Fatal( string message )
      {
         Log( TraceEventType.Critical, message );
      }

      /// <summary>
      /// Logs a fatal exception.
      /// </summary>
      /// <param name="message">The message.</param>
      /// <param name="ex">The exception or <c>null</c></param>
      public void Fatal( string message, Exception ex )
      {
         Log( TraceEventType.Critical, message, ex  );
      }

      /// <summary>
      /// Logs a fatal exception.
      /// </summary>
      /// <param name="ex">The ex.</param>
      /// <remarks>Fatal is the same as Critical.</remarks>
      public void Fatal( Exception ex )
      {
         Log( TraceEventType.Critical, ex.GetBaseException().ToString() );
      }

      private void Log( TraceEventType type, string message )
      {
         _source.TraceEvent( type, Thread.CurrentThread.ManagedThreadId, message );
      }

      private void Log( TraceEventType type, string message, Exception ex )
      {
         var text = new StringBuilder( message ?? string.Empty );
         if ( null != ex )
         {
            if ( text.Length > 0 )
            {
               text.AppendLine();
            }
            text.Append( ex.GetBaseException().ToString() );
         }

         Log( type, text.ToString() );
      }

      /// <summary>
      /// Flushes all logged information.
      /// </summary>
      public void Flush()
      {
         _source.Flush();
      }
   }
}